<?php

/**
 *  This is a basic Security User class witch
 *  allows users to signIn and out, check for
 *  credentials, and retrieve basic info(username, email, etc).
 *
 * @author     alara
 */
class appUser extends sfBasicSecurityUser
{
  protected
    $user = null;

  public function initialize(sfEventDispatcher $dispatcher, sfStorage $storage, $options = array())
  {
    parent::initialize($dispatcher, $storage, $options);

    if (!$this->isAuthenticated())
    {
      // remove user if timeout
      $this->getAttributeHolder()->removeNamespace('appUser');
      $this->user = null;
    }
  }

  public function getReferer($default)
  {
    $referer = $this->getAttribute('referer', $default);
    $this->getAttributeHolder()->remove('referer');

    return $referer ? $referer : $default;
  }

  public function setReferer($referer)
  {
    $this->setAttribute('referer', $referer);
  }

  public function hasCredential($credentials, $useAnd = true)
  {
    if (null === $this->getCredentials())
    {
      return false;
    }

    if (!is_array($credentials))
    {
      return in_array($credentials, $this->getCredentials());
    }

    // now we assume that $credentials is an array
    $test = false;

    foreach ($credentials as $credential)
    {
      // recursively check the credential with a switched AND/OR mode
      $test = $this->hasCredential($credential, $useAnd ? false : true);

      if ($useAnd)
      {
        $test = $test ? false : true;
      }

      if ($test) // either passed one in OR mode or failed one in AND mode
      {
        break; // the matter is settled
      }
    }

    if ($useAnd) // in AND mode we succeed if $test is false
    {
      $test = $test ? false : true;
    }

    return $test;
  }

  public function getCredentials()
  {
    if($this->isAuthenticated())
    {
      $app_user = ApplicationUserPeer::retrieveByPk($this->getAppUser()->getId());
      return $app_user->getCredentials();
    }
    return array();
  }

  public function signIn($user, $con = null)
  {
    // signin
    $this->setAttribute('user_id', $user->getId(), 'appUser');
    $this->setAuthenticated(true);
    $this->clearCredentials();
  }

  public function signOut()
  {
    $this->getAttributeHolder()->removeNamespace('appUser');
    $this->user = null;
    $this->setAuthenticated(false);
  }

  public function getAppUser()
  {
    if (!$this->user && $id = $this->getAttribute('user_id', null, 'appUser'))
    {
      $this->user = ApplicationUserPeer::retrieveByPk($id);

      if (!$this->user)
      {
        // the user does not exist anymore in the database
        $this->signOut();

        throw new sfException('The user does not exist anymore in the database.');
      }
    }

    return $this->user;
  }

  public function setTimedOut()
  {//Wether to setIt or default
    parent::setTimedOut();
  }

  // add some proxy method to the sfGuardUser instance

  public function __toString()
  {
    return $this->getAppUser()->__toString();
  }

  public function getUsername()
  {
    return $this->getAppUser()->getUsername();
  }

  public function getProfile()
  {
    return $this->getAppUser()->getProfile();
  }


  public function checkPassword($password)
  {
    return $this->getAppUser()->checkPassword($password);
  }

}
